Sys = {
	name	: 'BeeSphere UI Library',
	desc	: 'BeeSphere UI Library',
    version : '0.1',
    Device : {
    	name: navigator.userAgent.toLowerCase()
    },
    protocol: window.location.protocol
};
Lang = {
	TOKENS: {
		"\b": '\\b',
		"\t": '\\t',
		"\n": '\\n',
		"\f": '\\f',
		"\r": '\\r',
		'"' : '\\"',
		"\\": '\\\\'
	},
	Strings: {
		NULL: 'null',
		EMPTY: '',
		SPACE: ' '
	},
    isObject : function(x){
	    return x && typeof x == 'object';
	},
	isArray: function isArray(x) {
	    return ((typeof x == 'object') && (x.constructor == Array));
	},
	isHash: function(x) {
		return x instanceof Hash;
	},
	isFunction: function(x) {
		return typeof x == 'function';
	},
	isString: function(x) {
		return typeof x == 'string';
	},
	isInteger: function(x) {
		return isNumber (x) && (Math.floor(x) == x ? true : false);
	},
	isNumber: function(x) {
		return typeof x == 'number' && isFinite(x);
	},
	isDate: function(x) {
		return typeof x == 'date';
	},
	isBoolean: function(x) {
		return typeof x == 'boolean';
	},
	isUndefined: function(x) {
		return typeof x == 'undefined';
	},
	isEmpty: function (x){
		return x === null || x === undefined || ((Lang.isArray(x) && !x.length)) || false;
	},
	isPrimitive : function(x){
		return Lang.isString(x) || Lang.isNumber(x) || Lang.isBoolean(x);
	},
	isIterable: function (x) {
		if(Lang.isArray(x) || x.callee){
        	return true;
		}
	},      
	loop: function (ar, fn, scope){
	    if(Lang.isEmpty(ar, true)){
	        return;
	    }
	    if(!Lang.isIterable(ar) || Lang.isPrimitive(ar)){
	        ar = [ar];
	    }
	    for(var i = 0, len = ar.length; i < len; i++){
	        if(fn.call(scope || ar[i], ar[i], i, ar) === false){
	            return i;
	        };
	    }
	},
	define: function() {
	    var o, d;
	    Lang.loop (arguments, function (v) {
	        d = v.split(".");
	        o = window[d[0]] = window[d[0]] || {};
	        Lang.loop (d.slice(1), function (v2){
	            o = o[v2] = o[v2] || {};
	        });
	    });
	    return o;
	},
	copy: function (obj, members, force) {
		if (!members) {
			return;
		}
		if (force === undefined) {
			force = true;
		}
	    if (obj && members && typeof members == 'object'){
	        for (var p in members){
	        	if (force || Lang.isEmpty(obj[p])) {
	        		obj[p] = members[p];
	        	}
	        }
	    }
	    return obj;
	},
	matches: function (s, re){
		return re.test (s);
	}
};
Device = Sys.Device;
Strings = Lang.Strings;
var device = Device.name;
Lang.copy (Sys, {
	isOpera: Lang.matches(device, /opera/),
	isChrome: Lang.matches(device, /chrome/),
	isWebKit: Lang.matches(device, /webkit/),
	isSafari: !Sys.isChrome && Lang.matches(device, /safari/),
	isSafari2: Sys.isSafari && Lang.matches(device, /applewebkit\/4/), 
	isSafari3: Sys.isSafari && Lang.matches(device, /version\/3/),
	isSafari4: Sys.isSafari && Lang.matches(device, /version\/4/),
	isIE: !Sys.isOpera && Lang.matches(device, /msie/),
	isIE7: Sys.isIE && Lang.matches(device, /msie 7/),
	isIE8: Sys.isIE && Lang.matches(device, /msie 8/),
	isIE6: Sys.isIE && !Sys.isIE7 && !Sys.isIE8,
	isGecko: !Sys.isWebKit && Lang.matches(device, /gecko/),
	isGecko2: Sys.isGecko && Lang.matches(device, /rv:1\.8/),
	isGecko3: Sys.isGecko && Lang.matches(device, /rv:1\.9/),
	isBorderBox: Sys.isIE && !Sys.isStrict,
	isWindows: Lang.matches(device, /windows|win32/),
	isMac: Lang.matches(device, /macintosh|mac os x/),
	isAir: Lang.matches(device, /adobeair/),
	isLinux: Lang.matches(device, /linux/),
	isSecure: Lang.matches(Sys.protocol, /^https/i)
});

Lang.copy (Lang, {
	override: function (clazz, members) {
		var pt = clazz.prototype;
		Lang.copy (pt, members);
		if (Sys.isIE && members.toString != clazz.toString){
			pt.toString = members.toString;
		}
	},
	extend : function(){
		var io = function(o){
			for(var m in o){
				this[m] = o[m];
			}
		};
		var oc = Object.prototype.constructor;

		return function(sb, sp, overrides){
    		if(Lang.isObject(sp)){
        		overrides = sp;
        		sp = sb;
        		sb = overrides.constructor != oc ? overrides.constructor : function(){sp.copy (this, arguments);};
    		}
    		var F = function(){}, sbp, spp = sp.prototype;
    		F.prototype = spp;
    		sbp = sb.prototype = new F();
    		sbp.constructor=sb;
    		sb.superclass=spp;
    		if(spp.constructor == oc){
        		spp.constructor=sp;
			}
    		sb.override = function(o){
        		Lang.override(sb, o);
    		};
    		sbp.superclass = sbp.supr = (function(){
        		return spp;
    		});
    		sbp.override = io;
    		Lang.override(sb, overrides);
    		sb.extend = function(o){Lang.extend(sb, o);};
    		return sb;
		};
	}(),
	encode: function (x) {
		if(Lang.isUndefined(x) || x === null){
			return NULL;
		} else if (Lang.isArray(x)){
			return Lang.encodeArray(x);
		} else if (Lang.isDate (x)) {
			return Lang.encodeDate(x);
		} else if (Lang.isString (x)){
			return Lang.encodeString(x);
		} else if (Lang.isNumber (x)){
			return isFinite(x) ? String(x) : NULL;
		} else if (Lang.isBoolean(x)){
			return String(x);
		} else if (x.serialize) {
			return x.serialize ();
		} 
	},
	encodeString : function(s){
		if (/["\\\x00-\x1f]/.test(s)) {
			return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
				var c = Lang.TOKENS[b];
				if(c){
					return c;
				}
				c = b.charCodeAt();
				return "\\u00" +
					Math.floor(c / 16).toString(16) +
						(c % 16).toString(16);
			}) + '"';
		}
		return '"' + s + '"';
	},
	encodeArray : function(ar){
		var a = ["["], b, i, l = ar.length, v;
		for (i = 0; i < l; i += 1) {
			v = ar[i];
			switch (typeof v) {
				case 'undefined':
				case 'function':
				case 'unknown':
					break;
				default:
					if (b) {
						a.push(',');
					}
					a.push(v === null ? NULL : Lang.encode());
					b = true;
			}
		}
		a.push("]");
		return a.join("");
	},
	leftPad: function(p, ch) {
		if (!ch) {
			ch = "0";
		}
		return p < 10 ? ch + p : p;
	},
	encodeDate : function(d) {
		return '"' + d.getFullYear() + "-" +
			Lang.leftPad(d.getMonth() + 1) + "-" +
			Lang.leftPad(d.getDate()) + "T" +
			Lang.leftPad(d.getHours()) + ":" +
			Lang.leftPad(d.getMinutes()) + ":" +
			Lang.leftPad(d.getSeconds()) + '"';
    },
	toArray : function(){
		return Sys.isIE ?
			function(a, i, j, res){
				res = [];
				Lang.loop(a, function(v) {
					res.push(v);
				});
				return res.slice(i || 0, j || res.length);
			} :
			function(a, i, j){
				return Array.prototype.slice.call(a, i || 0, j || a.length);
			}
	}()
});
Lang.copy (Array.prototype, {
    indexOf : function(o){
        for (var i = 0, len = this.length; i < len; i++){
            if(this[i] == o){
                return i;
            }
        }
        return -1;
    },
	removeRange : function (from, to) {
		var rest = this.slice((to || from) + 1 || this.length);
		this.length = from < 0 ? this.length + from : from;
		return this.push.apply(this, rest);
	},
    remove : function(o){
        var index = this.indexOf(o);
        if(index != -1){
            this.splice(index, 1);
        }
		return index;
    }
}, false);
Lang.copy(String, {
	format : function(format){
		var args = Ext.toArray(arguments, 1);
		return format.replace(/\{(\d+)\}/g, function(m, i){
			return args[i];
		});
	}
});
Lang.copy(Object, {BS_CLASS_NAME: 'Bs.lang.Object'});
Lang.override (Object, {
	serialize : function () {
		var a = ['{'], b, i, v;
		for (i in this) {
			v = this[i];
			switch (typeof v) {
				case 'undefined':
				case 'function':
				case 'unknown':
					break;
				default:
					if(b){
						a.push(',');
					}
					a.push (Lang.encode(i), ':',
					v === null ? NULL : Lang.encode (v));
					b = true;
			}
		}
		a.push("}");
		return a.join(""); 
	},
	clone : function (src) {
		return Lang.copy ({}, src);
	}, 
	getClassName : function () {
		if (!this.classname) {
			var t = typeof this;
			if (t != "object") {
				this.classname = t;
			}
			var c = Object.prototype.toString.apply (this);
			c = c.substring (8, c.length-1);
			if (c != "Object") {
				this.classname = c;
			}
			if (this.constructor == Object) {
				this.classname = c;
			}
			var p = this.constructor.prototype;
			if ("classname" in p && typeof p.classname == "string") {
				this.classname = p.classname;
			}
			if (!this.classname) {
				this.classname = Object.BS_CLASS_NAME;
			}
		}
		return this.classname;
	}
});
Lang.define ('Bs.lang');
Bs.lang.Object = function (props) {
	Lang.copy (this, props);	
};